package thread;

/**
 * @author zxl
 * @version 1.0
 * @date 2021/10/26 20:52
 * 死锁：多个线程互相使用着对方需要的资源
 * 产生的原因：1 互斥条件：一个资源只能被一个线程同时使用
 *           2 请求与保持条件：一个线程因为请求资源而阻塞，对方不放弃使用本资源
 *           3 不剥夺条件：线程获得资源，在未使用完之前不能强行剥夺
 *           4 循环等待条件：若干线程形成首位相连的循环
 *
 * 排查：查看堆栈信息 1 打开终端命令
 *                 2 使用 ”jps -l“ 定位进程号
 *                 3 使用 ”jstack + 进程号“ 查看
 *
 */
public class Deadlock {
    public static void main(String[] args) {
       test1();
       test2();
    }
    //问题
    public static void test1(){
        ThreadTest1 test1 = new ThreadTest1("一号", 0);
        ThreadTest1 test2 = new ThreadTest1("二号", 1);
        new Thread(test1).start();
        new Thread(test2).start();
    }

    //解决
    public static void test2(){
        ThreadTest2 test1 = new ThreadTest2("一号", 0);
        ThreadTest2 test2 = new ThreadTest2("二号", 1);
        new Thread(test1).start();
        new Thread(test2).start();
    }

}

//车
class Car{

}
//枪
class Guns{

}
//问题
class ThreadTest1 implements Runnable{

    private static Car car = new Car();
    private static Guns guns = new Guns();

    private String name;
    private int role;

    public ThreadTest1(String name,int role) {
        this.name = name;
        this.role = role;
    }

    @Override
    public void run() {
        if(role==0){
            synchronized (car){
                System.out.println("用户"+name+"获得了车");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (guns){
                    System.out.println("用户"+name+"获得了枪");
                }
            }
        }else{
            synchronized (guns){
                System.out.println("用户"+name+"获得了枪");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (car){
                    System.out.println("用户"+name+"获得了车");
                }
            }
        }
    }
}
//解决
class ThreadTest2 implements Runnable {

    private static Car car = new Car();
    private static Guns guns = new Guns();

    private String name;
    private int role;

    public ThreadTest2(String name, int role) {
        this.name = name;
        this.role = role;
    }

    @Override
    public void run() {
        if (role == 0) {
            synchronized (car) {
                System.out.println("用户" + name + "获得了车");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (guns) {
                System.out.println("用户" + name + "获得了枪");
            }
        } else {
            synchronized (guns) {
                System.out.println("用户" + name + "获得了枪");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (car) {
                System.out.println("用户" + name + "获得了车");
            }
        }
    }
}
